export function downloadFileByUrl(data: string | Blob, name?: string) {
    let url = '';
    if (typeof data === 'string') {
        url = data;
    } else if (data instanceof Blob) {
        url = URL.createObjectURL(data);
    }
    if (url) {
        const downloadLink = document.createElement('a');
        document.body.appendChild(downloadLink);
        downloadLink.href = url;
        if (name) {
            downloadLink.download = name;
        }
        downloadLink.click();
        URL.revokeObjectURL(url);
        document.body.removeChild(downloadLink);
    }
}

export function formatFileSize(size: number, decimals: number = 3): string {
    size = size / 1024;
    const unit = ['kb', 'mb', 'gb'];
    let max = unit.length;
    let start = 0;
    if (size > 1024 && start < max) {
        size = size / 1024;
        start++;
    }
    return `${parseFloat(size.toFixed(decimals))}${unit[start]}`;
}

export async function imageFileToBase64(image: File): Promise<string> {
    const reader = new FileReader();
    reader.readAsDataURL(image);
    return new Promise<string>((resolve) => {
        reader.onload = () => {
            resolve(reader.result as string);
        };
    });
}

// export function createMutationObserver(domNode: HTMLElement, callback: MutationCallback, config: MutationObserverInit = { attributes: true, childList: true, subtree: true }): MutationObserver {
//     const observer = new MutationObserver(callback);
//     observer.observe(domNode, config);
//     return observer;
// }

export function base64Encode(str: string) {
    return btoa(
        encodeURIComponent(str).replace(/%([0-9A-F]{2})/g, (_match, p1) => {
            return String.fromCharCode(Number('0x' + p1));
        })
    );
}

export async function getImageDimension(image: File | string): Promise<[number, number]> {
    let imgSrc = '';
    if (image instanceof File) {
        imgSrc = await imageFileToBase64(image);
    } else {
        imgSrc = image;
    }
    const imgElement = document.createElement('img');
    imgElement.style.visibility = 'hidden';
    imgElement.style.position = 'fixed';
    imgElement.src = imgSrc;
    document.body.appendChild(imgElement);
    return await new Promise<[number, number]>((resolve) => {
        setTimeout(() => {
            resolve([imgElement.width, imgElement.height]);
            document.body.removeChild(imgElement);
        }, 100);
    });
}
